package cn.gov.msa.util;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * <b>同步锁：</b><br/>
 * 主要作用是在服务器集群环境下保证方法的synchronize；<br/>
 * 标记在方法上，使该方法的执行具有互斥性，并不保证并发执行方法的先后顺序；<br/>
 * 如果原有“A任务”获取锁后任务执行时间超过最大允许持锁时间，且锁被“B任务”获取到，在“B任务”成功货物锁会并不会终止“A任务”的执行；<br/>
 * <br/>
 * <b>注意：</b><br/>
 * 使用过程中需要注意expire、toWait、sleepMills、maxSleepMills等参数的场景使用；<br/>
 * 需要安装redis，并使用spring和spring-data-redis等，借助redis NX等方法实现。
 * 
 */
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RedisSynLock {
 
	/**
	 * 锁的key<br/>
	 * 如果想增加坑的个数添加非固定锁，可以在参数上添加@RedisSynLock注解，但是本参数是必写选项<br/>
	 * 
	 */
	String synKey();
 
	/**
	 * 持锁时间，超时时间，持锁超过此时间自动丢弃锁<br/>
	 * 单位毫秒,默认20秒<br/>
	 */
	long expire() default 20 * 1000;
 
	/**
	 * 当获取锁失败，是继续等待还是放弃<br/>
	 * 默认为放弃
	 */
	boolean toWait() default false;
 
	/**
	 * 没有获取到锁的情况下且toWait()为继续等待，睡眠指定毫秒数继续获取锁，也就是轮训获取锁的时间<br/>
	 * 默认为100毫秒
	 * 
	 * @return
	 */
	long sleepMills() default 100;
 
	/**
	 * 锁获取超时时间：<br/>
	 * 没有获取到锁的情况下且toWait()为true继续等待，最大等待时间，如果超时抛出
	 * {@link java.util.concurrent.TimeoutException.TimeoutException}
	 * ，可捕获此异常做相应业务处理；<br/>
	 * 单位毫秒,默认一分钟，如果设置为0即为没有超时时间，一直获取下去；
	 * 
	 * @return
	 */
	long maxSleepMills() default 60 * 1000;
}

